﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using LinqToLfsWorld;
using LinqToLfsWorld.Serialization;
using LinqToLfsWorld.Interface;

namespace LibraryTest
{
	/// <summary>
	/// Contains a variety of test methods which examine the serialization capabilities of the
	/// LinqToLfsWorld library.
	/// </summary>
	[TestClass]
	public class SerializationTests
	{

		private RacerStats _myStats = null;

		public SerializationTests()
		{

			using (LfsWorldContext context = new LfsWorldContext())
			{

				// Retrieve a fully-populated entity for use in our tests.
				_myStats = (from stat in context.RacerStats
						   where stat.RacerName == "elkdanger"
						   select stat).Single();

			}

		}

		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }
		//
		// Use TestInitialize to run code before running each test 
		// [TestInitialize()]
		// public void MyTestInitialize() { }
		//
		// Use TestCleanup to run code after each test has run
		// [TestCleanup()]
		// public void MyTestCleanup() { }
		//
		#endregion

		/// <summary>
		/// Performs a basic serialization test on the entities.
		/// </summary>
		/// <remarks>At the moment the real test here is to make sure no exceptions are thrown during serialization.
		/// The entities should be able to serialize to Xml, SOAP and Binary formats ok.</remarks>
		[TestMethod]
		public void BasicSerializationTest()
		{
			JsonSerializer<ILfsWorldEntity> s = new JsonSerializer<ILfsWorldEntity>();
			string serialized = s.Serialize(_myStats);

			RacerStats stats = (RacerStats)s.Deserialize(serialized);
		}

		[TestMethod]
		public void JsonSerializationTest()
		{
			RacerFuel fuel = new RacerFuel();
			fuel.RacerName = "elkdanger";
			fuel.FuelPercentage = 12.5f;
			fuel.TrackIdent = "000";
			fuel.TrackName = LinqToLfsWorld.Utility.CircuitNameFactory.GetNameFromIdent(fuel.TrackIdent);
			fuel.Car = CarTypes.BF1;

			JsonSerializer<RacerFuel> s = new JsonSerializer<RacerFuel>();
			string serialized = s.Serialize(fuel);

			RacerFuel fuelOut = s.Deserialize(serialized);

			Assert.AreEqual(fuel.RacerName, fuelOut.RacerName);
			Assert.AreEqual(fuel.FuelPercentage, fuelOut.FuelPercentage);
			Assert.AreEqual(fuel.TrackIdent, fuelOut.TrackIdent);
			Assert.AreEqual(fuel.TrackName, fuelOut.TrackName);
			Assert.AreEqual(fuel.Car, fuelOut.Car);
		}

		[TestMethod]
		public void XmlSerializationTest()
		{
			RacerFuel fuel = new RacerFuel();
			fuel.RacerName = "elkdanger";
			fuel.FuelPercentage = 12.5f;
			fuel.TrackIdent = "000";
			fuel.TrackName = LinqToLfsWorld.Utility.CircuitNameFactory.GetNameFromIdent(fuel.TrackIdent);
			fuel.Car = CarTypes.BF1;

			XmlSerializer<RacerFuel> s = new XmlSerializer<RacerFuel>();
			string serialized = s.Serialize(fuel);

			RacerFuel fuelOut = s.Deserialize(serialized);

			Assert.AreEqual(fuel.RacerName, fuelOut.RacerName);
			Assert.AreEqual(fuel.FuelPercentage, fuelOut.FuelPercentage);
			Assert.AreEqual(fuel.TrackIdent, fuelOut.TrackIdent);
			Assert.AreEqual(fuel.TrackName, fuelOut.TrackName);
			Assert.AreEqual(fuel.Car, fuelOut.Car);
		}

		[TestMethod]
		public void AllEntitySerializationTest()
		{

			// Makes sure all the entities are capable of serializing
			List<ILfsWorldEntity> entityList = new List<ILfsWorldEntity>();
			entityList.Add(new RacerStats());
			entityList.Add(new RacerFuel());
			entityList.Add(new WorldRecord());
			entityList.Add(new Hotlap());
			entityList.Add(new HotlapChartEntry());
			entityList.Add(new HotlapLogEntry());
			entityList.Add(new Team());
			entityList.Add(new Host());
			entityList.Add(new PersonalBest());

			foreach (ILfsWorldEntity entity in entityList)
			{
				XmlSerializer<ILfsWorldEntity> serializer = new XmlSerializer<ILfsWorldEntity>();
				string serialized = serializer.Serialize(entity);

				ILfsWorldEntity deserialized = serializer.Deserialize(serialized);
			}

		}

	}
}
